package com.xiaotu.spider.project.pageprocessor;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.xiaotu.common.exception.SpiderException;
import com.xiaotu.common.exception.SpiderExceptionCode;
import com.xiaotu.common.util.DateUtils;
import com.xiaotu.common.util.FileUtil;
import com.xiaotu.common.util.HtmlUtil;
import com.xiaotu.common.util.PageUtils;
import com.xiaotu.common.util.RegexUtils;
import com.xiaotu.common.util.SepratorUtil;
import com.xiaotu.spider.APageProcessor;

import net.sf.json.JSONObject;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Request;
import us.codecraft.webmagic.selector.Html;

/**
 * @类名 MicroBlogTopicPageProcessor
 * @日期 2017年5月22日
 * @作者 高海军
 * @功能 官微话题数据爬取
 */
@Component("MicroBlogTopicPageProcessor")
@Scope("prototype")
public class MicroBlogTopicPageProcessor extends APageProcessor
{
	
	private static final String REX_TIME_RECENT = "[0-9]{2}月[0-9]{2}日 [0-9]{2}:[0-9]{2}";
	
	private static final String REX_TIME_HISTORY = "[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}";
	
	private static final String[] REX_TARGET = new String[] {
			"赞\\[" + RegexUtils.REGEX_INTEGER + "\\]</a>",
			"转发\\[" + RegexUtils.REGEX_INTEGER + "\\]</a>",
			"评论\\[" + RegexUtils.REGEX_INTEGER + "\\]</a>" };
	
	private Date startDate = DateUtils.fomartStringToDate("2015-01-01",
			DateUtils.DAY_FORMAT);
	private Date endDate = new Date();
	private String fileName;
	
	@Override
	public void initRunParams(Map<String, Object> map)
	{
		if (map.get("startDate") != null)
			startDate = DateUtils.fomartStringToDate(
					map.get("startDate") + StringUtils.EMPTY,
					DateUtils.DAY_FORMAT);
		if (map.get("endDate") != null)
			endDate = DateUtils.fomartStringToDate(
					map.get("endDate") + StringUtils.EMPTY,
					DateUtils.DAY_FORMAT);
		if (map.get("fileName") == null)
			throw new SpiderException(
					SpiderExceptionCode.PageProcessorParameterErrorException);
		fileName = FileUtil
				.getCacheFilePath(map.get("fileName") + StringUtils.EMPTY);
	}
	
	@Override
	protected Request getStartRequest(JSONObject target)
	{
		target.putAll(this.getOtherTarget());
		return new Request(
				target.getString("url").replace("weibo.com", "weibo.cn"));
	}
	
	private String[] getTarget(String divStr)
	{
		List<String> valueList = new ArrayList<String>();
		for (String regx : REX_TARGET)
		{
			String value = RegexUtils.regexSearch(regx, divStr);
			if (StringUtils.isEmpty(value))
				throw new SpiderException(
						SpiderExceptionCode.DataInvalideException);
			value = RegexUtils.regexSearch(RegexUtils.REGEX_INTEGER, value);
			valueList.add(value);
		}
		return valueList.toArray(new String[valueList.size()]);
	}
	
	@Override
	public void process(Page page)
	{
		List<String> divList = page.getHtml().xpath("//div[@class='c' and @id]")
				.all();
		if (divList == null || divList.isEmpty())
			throw new SpiderException(
					SpiderExceptionCode.DataInvalideException);
		
		boolean loadMore = true;
		for (String divStr : divList)
		{
			String time = this.getTime(divStr);
			if (!needTopic(time))
			{
				loadMore = false;
				continue;
			}
			String content = new Html(divStr).xpath("//span[@class='ctt']")
					.get();
			content = HtmlUtil.delHTMLTag(content).replaceAll("&nbsp;",
					SepratorUtil.SEP_SPACE_EN);
			String[] targetArr = this.getTarget(divStr);
			FileUtil.writeFile(fileName,
					time + SepratorUtil.SEP_PIPE + content
							+ SepratorUtil.SEP_PIPE
							+ StringUtils.join(targetArr, SepratorUtil.SEP_PIPE)
							+ SepratorUtil.LINE_SEPRATOR);
		}
		
		if (loadMore)
		{
			String link = page.getHtml().xpath("//form/div/a/@href").get();
			if (StringUtils.isNotEmpty(link))
				PageUtils.addTargetRequest(page, link,
						page.getRequest().getExtras());
		}
	}
	
	private boolean needTopic(String time)
	{
		if (StringUtils.isEmpty(time))
			return false;
		Date currDate = DateUtils.fomartStringToDate(time,
				DateUtils.SECONDS_FORMAT);
		return (currDate.before(this.endDate)
				&& currDate.after(this.startDate));
	}
	
	private String getTime(String divStr)
	{
		String time = RegexUtils.regexSearch(REX_TIME_RECENT, divStr);
		if (StringUtils.isEmpty(time))
			time = RegexUtils.regexSearch(REX_TIME_HISTORY, divStr);
		else
			time = DateUtils.getDateString(new Date(), DateUtils.YEAR_FORMAT)
					+ SepratorUtil.SEP_CROSS_EN
					+ RegexUtils.replaceStr(
							RegexUtils.replaceStr(time, "月",
									SepratorUtil.SEP_CROSS_EN),
							"日", StringUtils.EMPTY)
					+ ":00";
		
		return time;
	}
	
	@Override
	protected String getSpiderType()
	{
		return "MicroBlogTopic";
	}
	
	@Override
	public String getPageDataType(Page page)
	{
		return "MicroBlogTopic";
	}
}
